﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Windows.Forms;
using AgingTest.Tools;

namespace AgingTest.DataProcess
{
    /// <summary>
    /// 用于管理串口相关工作
    /// </summary>
    class COMConnect
    {
        
        
        /// <summary>
        /// 定义数据上传委托
        /// </summary>
        /// <param name="strMsg">发送给主窗体的消息</param>
        public delegate void ExecUploadEvent(string strMsg,byte[] buffer);

        /// <summary>
        /// 定义ExecUploadEvent委托事件
        /// </summary>
        public static event ExecUploadEvent OnExecUploadEvent;

        //定义串口出错消息
        public delegate void COMErrMsgEvent(string Msg);
        public static event COMErrMsgEvent OnCOMErrMsgEvent;

        public static SerialPort COM1 = new SerialPort();
        public static byte[] RecieveBuff = new byte[2048];//全局缓冲接收区
        //接收等待信号量
        public static bool WaitForRecive = false;

        //数据是否接收完标示符
        private static bool IsComplete = true;     //true：表明在等待接收新的数据    false：继续组装上一次的数据       
        private static int CurrentInsert = 0;  //当前需要的插入点
        private static int IndexStart = 0;      //数据起始位置
        private static int ValidateLen = 0;     //有效的数据长度

        /// <summary>
        /// 打开串口
        /// </summary>
        /// <returns></returns>
        public static string ComOpen()
        {
            try
            {
                COM1.Open();
                COM1.DataReceived += new SerialDataReceivedEventHandler(COM1_DataReceived);
                return "OK";

            }
            catch (Exception ex)
            {

                COM1.Close();
                COM1.DataReceived -= new SerialDataReceivedEventHandler(COM1_DataReceived);
                return ex.Message;
                //sp1.DataReceived -= new SerialDataReceivedEventHandler(sp1_DataReceived);
                //throw;
            }
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <returns></returns>
        public static string ComClose()
        {
            try
            {
                COM1.Close();
                COM1.DataReceived -= new SerialDataReceivedEventHandler(COM1_DataReceived);
                return "OK";
            }
            catch (Exception ex)
            {

                throw;
            }
        }


        public static void COM1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] TempBuff = new byte[2048];
            Array.Clear(TempBuff, 0, 2048);
            int Count = COM1.BytesToRead;
            if (Count > 2048)
            {
                Count = 2048;
                COM1.Read(TempBuff, 0, Count);
            }
            else
            {
                COM1.Read(TempBuff, 0, COM1.BytesToRead);
            }



            
            //接收数据  这里处理有效数据的截取、数据可能多次才能传输完成的情况
            if (IsComplete == true)     //表示接收新的数据包
            {
                IndexStart = Array.FindIndex(TempBuff, (r) => r == 0x0D);
                if (IndexStart<0)
                {
                    return;
                }
                //获取这一帧数据的长度
                ValidateLen = BitConverter.ToUInt16(TempBuff, IndexStart + 1);
                if (ValidateLen > 1000) return;
                //判断是否接收到完整数据

                if (ValidateLen > (Count - IndexStart))     //表明这一帧数据没有完整等待下一帧
                {
                    Array.Copy(TempBuff, IndexStart, RecieveBuff, 0, (Count - IndexStart));
                    CurrentInsert = Count - IndexStart;
                    IsComplete = false;
                    return;
                }
                else if (ValidateLen < (Count-IndexStart))  //表明数据发多了，需要截取
                {
                    Array.Copy(TempBuff, IndexStart, RecieveBuff, 0, ValidateLen);
                    IsComplete = true;
                }
                else                                        //相等的情况
                {
                    Array.Copy(TempBuff, IndexStart, RecieveBuff, 0, ValidateLen);
                    IsComplete = true;
                }
                                                                               
            }
            else        //表明数据没有完整，继续上一次的接收
            {
                if ( ValidateLen > (CurrentInsert+Count) ) //表示还没有接收完
                {
                    Array.Copy(TempBuff, 0, RecieveBuff, CurrentInsert, Count);
                    CurrentInsert += Count;
                    IsComplete = false;
                    return;
                }
                else if ( ValidateLen <= (CurrentInsert+Count) ) //表明已经接收到足够长度的数据 进行截取
                {
                    Array.Copy(TempBuff, 0, RecieveBuff, CurrentInsert, Count);
                    CurrentInsert += Count;
                    IsComplete = true;
                    //清空不相关的数据
                    Array.Clear(RecieveBuff, ValidateLen, 2048 - ValidateLen);
                }                    
            }
            //这里把标志都清零
            CurrentInsert = 0;
            IsComplete = true;
            
            //把数据进行CRC校验
            var crc = CRC32.Calculate_CRC32_uint(RecieveBuff, ValidateLen - 5);
            var buffCRC= BitConverter.ToUInt32(RecieveBuff, ValidateLen - 5);
            if (crc != buffCRC)     //直接丢弃这一帧数据
            {
                return;
            }




            //string strRecieve3 = System.Text.Encoding.Default.GetString(TempBuff, 0, Count);
            byte[] TempData = new byte[ValidateLen];
            Array.Copy(RecieveBuff, TempData, ValidateLen);        
            //Array.Copy(TempBuff, 0, TempData, 0, Count);

            OnExecUploadEvent?.Invoke("OK", TempData);

        }


        public static void COM1_DataSend(ref byte[] data)
        {
            //发送之前把接字符串清空
            //Array.Clear(RecieveBuff, 0, 2048);
            try
            {
                COM1.Write(data, 0, data.Length);
            }
            catch (Exception ex)
            {
                OnCOMErrMsgEvent?.Invoke(ex.Message);
                //throw;
            }
        }



        


    }
}
